package com.hpe.javawebsocketdemo.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hpe.javawebsocketdemo.module.MsgData;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@ServerEndpoint(value = "/websocket/{nickname}")
public class WebsocketService {

    /**
     * 用来存放每个客户端对应的websocket对象
     */
    private static final CopyOnWriteArraySet<WebsocketService> websocketSet = new CopyOnWriteArraySet<>();

    /**
     * 与某个客户端的连接会话, 需要通过它来给客户端发送数据
     */
    private Session session;

    private static final Map<String, Session> map = new HashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("nickname") String nickname) {
        if (map.containsKey(nickname)) {
            session.getAsyncRemote().sendText("该用户已存在");
            return;
        }
        this.session = session;
        map.put(nickname, session);
        websocketSet.add(this);
        System.out.println("有新连接加入:" + nickname + ",当前在线人数为" + websocketSet.size());
        this.session.getAsyncRemote().sendText("恭喜:" + nickname + " 成功连接上WebSocket(其频道号：" + session.getId() + ")-->当前在线人数为：" + websocketSet.size());
    }

    @OnClose
    public void onClose() {
        websocketSet.remove(this);
        String nickname = this.session.getPathParameters().get("nickname");
        map.remove(nickname);
        System.out.println("有一连接关闭！" + nickname + ", 当前在线人数为" + websocketSet.size());
    }

    @OnMessage
    public void onMessage(String message, Session session, @PathParam("nickname") String nickname) {
        System.out.println("来自客户端的消息-->" + nickname + ": " + message);
        //从客户端传过来的数据是json数据，所以这里使用jackson进行转换为SocketMsg对象，
        // 然后通过socketMsg的type进行判断是单聊还是群聊，进行相应的处理:
        ObjectMapper objectMapper = new ObjectMapper();
        MsgData msgData;
        try {
            msgData = objectMapper.readValue(message, MsgData.class);
            if (!map.containsKey(msgData.getToUser())) {
                session.getAsyncRemote().sendText("该用户不存在");
                return;
            }
            // 单聊
            if (msgData.getType() == 1) {
                msgData.setFromUser(nickname);
                Session toSession = map.get(msgData.getToUser());
                String sendMsg = String.format("%s->%s: %s", nickname, toSession.getPathParameters().get("nickname"), msgData.getMessage());
                session.getAsyncRemote().sendText(sendMsg);
                if (!msgData.getToUser().equals(msgData.getFromUser())) {
                    toSession.getAsyncRemote().sendText(sendMsg);
                }
            } else if (msgData.getType() == 0) {
                // 群发
                for (WebsocketService item : websocketSet) {
                    item.session.getAsyncRemote().sendText(nickname + ": " + msgData.getMessage());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误: " + session.toString());
        error.printStackTrace();
    }


}
